#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

template <typename T>
class Stack
{
private:
  T* _top;
  T* _base;
  uint16_t _capacity;

public:
  uint16_t Size() {
    return _top - _base;
  }

  uint16_t Capacity() {
    return _capacity;
  }

  Stack()
    :_capacity(5)
  {
    _base = new T[_capacity];
    memset(_base, 0, _capacity);
    _top = _base;
  }

  Stack(uint16_t capacity)
    :_capacity(capacity)
  {
    _base = new T[_capacity];
    memset(_base, 0, _capacity);
    _top = _base;
  }

  ~Stack()
  {
    if (_base != nullptr) {
      printf("~Stack()\n");
      delete[] _base;
      _base = _top = nullptr;
    }
  }

  bool Empty() {
    return _base == _top;
  }

  bool Full() {
    return _top - _base == _capacity;
  }

  bool Push(const T& e) {
    if (Full()) {
      fprintf(stderr, "stack is full.\n");
      return false;
    }
    *_top++ = e; // *_top = e; _top++;
    return true;
  }

  T Pop() {
    if (Empty()) {
      fprintf(stderr, "stack is empty.\n");
      exit(-1);
    }
    return *--_top; // --_top; return *top;
  }

  T Top() {
    if (Full()) {
      fprintf(stderr, "stack is full.\n");
      exit(-1);
    }
    return *(_top - 1);
  }

};

